<template>
    <div>
        <div class="component-upload-image" style="display: flex">
            <el-popover placement="right" trigger="hover" :disabled="popoverDisabled">
                <div class="upload-img-wrap" v-show="fileList.length > 0" slot="reference">
                    <div class="upload-img-box readOnly" @mouseenter="mouseenter" @mouseout="mouseout">
                        <el-image class="upload-img" :src="mainImg" :preview-src-list="fileList.map(item => item.url)"></el-image>
                        <div class="upload-icon" :class="{ show: hover }" v-if="!readOnly">
                            <i class="el-icon-delete" @click="handleRemove" @mouseenter="mouseenter" @mouseout="mouseout"></i>
                            <i class="el-icon-zoom-in" @click="handlePictureCardPreview" @mouseenter="mouseenter" @mouseout="mouseout"></i>
                        </div>
                    </div>
                </div>
                <div v-if="hoverType=='copy'">
                    <div>
                        <el-button type="text" @click="copy('Color')">同Color变种</el-button>
                    </div>
                    <div style="margin-top: 4px">
                        <el-button type="text" @click="copy('CupSize')">同CupSize变种</el-button>
                    </div>
                    <div style="margin-top: 4px">
                        <el-button type="text" @click="copy('Cup')">同Cup变种</el-button>
                    </div>
                </div>
                <div v-else-if="hoverType=='hover'">
                    <slot name="hover"></slot>
                </div>
            </el-popover>
            <div class="upload-img-box" v-if="!readOnly && fileList.length < limit">
                <div class="upload-img-error">
                    <el-popover placement="right" trigger="hover">
                        <div class="img-add" slot="reference">
                            <i class="el-icon-plus"></i>
                            <span>选择图片</span>
                        </div>
                        <div>
                            <div>
                                <el-upload
                                    :disabled="disabled"
                                    :action="uploadImgUrl"
                                    list-type="text"
                                    :on-success="handleUploadSuccess"
                                    :before-upload="handleBeforeUpload"
                                    :limit="limit"
                                    :on-error="handleUploadError"
                                    :on-exceed="handleExceed"
                                    name="file"
                                    :show-file-list="false"
                                    :on-remove="handleRemove"
                                    :headers="headers"
                                >
                                    <div>本地图片</div>
                                </el-upload>
                            </div>
                            <div style="margin-top: 4px">
                                <div @click="imgVisible = true">网络图片</div>
                            </div>
                        </div>
                    </el-popover>
                </div>
            </div>
        </div>
        <el-dialog :visible.sync="imgVisible" title="从网络地址(URL)选择图片" width="600" append-to-body v-loading="save">
            <el-input type="textarea" v-model="urlImgs" :rows="8" placeholder="请填写URL地址，多个地址回车换行"></el-input>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" :loading="save" :disabled="save" @click="uploadUrlImages">添加</el-button>
                <el-button @click="imgVisible = false">取 消</el-button>
            </div>
        </el-dialog>
        <el-image-viewer v-if="dialogVisible" :on-close="closeViewer" :url-list="fileList.map(pre => pre.url)" :z-index="3000" />
    </div>
</template>

<script>
import { getToken } from '@/utils/auth'
import { uploadUrlImages } from '@/api/product'
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
export default {
    components: { ElImageViewer },
    props: {
        value: [String, Object, Array],
        popoverDisabled: {
            type: Boolean,
            default: true,
        },
        hoverType: {
            type: String,
            default: 'copy',
        },
        // 图片数量限制
        limit: {
            type: Number,
            default: 1,
        },
        // 大小限制(MB)
        fileSize: {
            type: Number,
            default: 5,
        },
        // 文件类型, 例如['png', 'jpg', 'jpeg']
        fileType: {
            type: Array,
            default: () => ['png', 'jpg', 'jpeg'],
        },
        // 是否显示提示
        isShowTip: {
            type: Boolean,
            default: true,
        },
        disabled: Boolean,
        readOnly: {
            type: Boolean,
            default: false,
        },
    },
    data() {
        return {
            imageModel: '',
            urlImgs: '',
            dialogImageUrl: '',
            imgVisible: false,
            save: false,
            hover: false,
            dialogVisible: false,
            hideUpload: false,
            uploadImgUrl: process.env.VUE_APP_BASE_API + '/api/UploadInfo/uploadImages', // 上传的图片服务器地址
            headers: {
                token: getToken(),
            },
            fileList: [],
            isShowFileList: true,
        }
    },
    watch: {
        value: {
            handler(val) {
                if (val) {
                    // 首先将值转为数组
                    const list = Array.isArray(val) ? val : this.value.split(',')
                    
                    // 然后将数组转为对象数组
                    this.fileList = list.map(item => {
                        if (typeof item === 'string') {
                            item = { name: item, url: item, hover: false }
                        }
                        return item
                    })
                } else {
                    this.fileList = []
                    return []
                }
            },
            deep: true,
            immediate: true,
        },
    },
    computed: {
        mainImg() {
            return this.fileList?.[0]?.url ?? ''
        },
        // 是否显示提示
        showTip() {
            return this.isShowTip && (this.fileType || this.fileSize)
        },
    },
    methods: {
        copy(type) {
            this.$emit('copyToOther', type)
        },
        changeImageModel() {
            if (this.imageModel === 'onlineImage') {
                this.imgVisible = true
            }
        },
        uploadUrlImages() {
            this.save = true
            const params = {
                images_urls: this.urlImgs,
            }
            uploadUrlImages(params)
                .then(res => {
                    if (res.code != 0) {
                        res.data.map(item => {
                            this.fileList.push({
                                name: item,
                                url: item,
                                hover: false,
                            })
                        })

                        let result = {
                            list: this.listToString(this.fileList),
                            limit: this.limit,
                        }
                        this.urlImgs = ''
                        this.$emit('uploadInput', result)
                        //返回 v-model的参数（关键）
                        this.$emit('input', this.listToString(this.fileList))
                    }
                })
                .finally(() => {
                    this.save = false
                    this.imgVisible = false
                })
        },
        mouseenter() {
            this.hover = true
        },
        mouseout() {
            this.hover = false
        },
        // 删除图片
        handleRemove(file) {
            if (!file) {
                this.fileList.splice(0, 1)
            } else {
                const findex = this.fileList.map(f => f.name).indexOf(file.name)
                this.fileList.splice(findex, 1)
            }

            this.$emit('uploadInput', {
                list: this.listToString(this.fileList),
                limit: this.limit,
            })
        },
        // 上传成功回调
        handleUploadSuccess(res) {
            if (res.code != 0) {
                this.fileList.push({
                    name: res?.fileName ?? '',
                    url: res.data,
                })
                let result = {
                    list: this.listToString(this.fileList),
                    limit: this.limit,
                }
                this.$emit('uploadInput', result)
                //返回 v-model的参数（关键）
                this.$emit('input', this.listToString(this.fileList))
            } else {
                this.isShowFileList = false
                this.fileList = []
                this.$message({
                    type: 'error',
                    message: res.msg,
                })
            }

            this.loading.close()
        },
        // 上传前loading加载
        handleBeforeUpload(file) {
            let isImg = false
            if (this.fileType.length) {
                let fileExtension = ''
                if (file.name.lastIndexOf('.') > -1) {
                    fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
                }
                isImg = this.fileType.some(type => {
                    if (file.type.indexOf(type) > -1) return true
                    if (fileExtension && fileExtension.indexOf(type) > -1) return true
                    return false
                })
            } else {
                isImg = file.type.indexOf('image') > -1
            }

            if (!isImg) {
                this.$message.error(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`)
                return false
            }
            if (this.fileSize) {
                const isLt = file.size / 1024 / 1024 < this.fileSize
                if (!isLt) {
                    this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`)
                    return false
                }
            }
            this.loading = this.$loading({
                lock: true,
                text: '上传中',
                background: 'rgba(0, 0, 0, 0.7)',
            })
        },
        // 文件个数超出
        handleExceed() {
            this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`)
        },
        // 上传失败
        handleUploadError() {
            this.$message({
                type: 'error',
                message: '上传失败',
            })
            this.loading.close()
        },
        // 预览
        handlePictureCardPreview() {
            this.dialogVisible = true
        },
        closeViewer() {
            this.dialogVisible = false
        },
        // 对象转成指定字符串分隔
        listToString(list, separator) {
            let strs = ''
            separator = separator || ','
            for (const i in list) {
                strs += list[i].url + separator
            }
            return strs != '' ? strs.substr(0, strs.length - 1) : ''
        },
    },
}
</script>
<style scoped lang="scss">
// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {
    display: none;
}
// 去掉动画效果
::v-deep .el-list-enter-imageModel,
::v-deep .el-list-leave-imageModel {
    transition: all 0s;
}

::v-deep .el-list-enter,
.el-list-leave-imageModel {
    opacity: 0;
    transform: translateY(0);
}
.upload-img-wrap {
    width: 76px;
    overflow-y: auto;
    display: flex;
    position: relative;
}

.upload-img-box {
    width: 70px;
    height: 70px;
    border: 1px dashed #c0ccda;
    background-color: #fbfdff;
    border-radius: 2px;
    position: relative;
    margin-right: 8px;
}
.upload-img-box.readOnly {
    margin-right: 0;
    overflow: hidden;
}
.upload-img {
    width: 68px;
    height: 68px;
    background-color: #fbfdff;
    border-radius: 2px;
    flex-shrink: 0;
}
.upload-icon {
    position: absolute;
    z-index: 10;
    top: 0;
    left: 0;
    width: 68px;
    height: 68px;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
}
.upload-icon.show {
    opacity: 1;
}
.upload-img-popover {
    position: absolute;
    z-index: 10;
    top: 0;
    right: 100%;
    background: #fff;
    min-width: 150px;
    border-radius: 4px;
    border: 1px solid #ebeef5;
    // color: #606266;
    // line-height: 1.4;
    text-align: justify;
    // font-size: 14px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    word-break: break-all;
}
.upload-icon i {
    font-size: 16px;
    color: #fff;
}
.upload-icon i + i {
    margin-left: 16px;
}
.img-add,
.upload-img-error {
    width: 68px;
    height: 68px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.img-add i {
    font-size: 18px;
    margin-bottom: 4px;
}
</style>
